package com.cosc716.application.gui.components;

import java.awt.GridLayout;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.cosc716.simulator.SimulationContext;
import com.cosc716.simulator.Simulator;
import com.cosc716.restaurant.domain.collections.OrderQueue;
import com.cosc716.restaurant.domain.collections.WaitingQueue;
import com.cosc716.restaurant.system.SystemInterface;

public class SimulatorPanel extends JPanel implements ChangeListener, Observer {
	
	private final String TIME_INTERVAL_SLIDER_COMBO = "TIME_INTERVAL_SLIDER_COMBO";
	private final String PATRON_EAT_TIME_SLIDER_COMBO = "PATRON_EAT_TIME_SLIDER_COMBO";
	private final String PREP_CAPACITY_SLIDER_COMBO = "PREP_CAPACITY_SLIDER_COMBO";

	private JLabel waitQueueLabel;
	private JLabel orderQueueLabel;
	
	private static final long serialVersionUID = -5652460150965896130L;
	
	private Simulator simulator;
	
	public SimulatorPanel(Simulator simulator) {
		this.simulator = simulator;
		
		addComponents();
	}
	
	private void addComponents() {
		
		// Control for simulator time intervals
		SliderAndSpinnerComboPanel timeIntervalSlider = 
				new SliderAndSpinnerComboPanel(
						TIME_INTERVAL_SLIDER_COMBO,
						"Simulator Time Intervals:",
						SimulationContext.MIN_TIME_INTERVALS,
						//SimulationContext.MAX_TIME_INTERVALS,
						720,
						360);
		SliderAndSpinnerComboPanel patronEatTimeSlider = 
				new SliderAndSpinnerComboPanel(
						PATRON_EAT_TIME_SLIDER_COMBO,
						"Time for patrons to eat their meal:",
						3,
						30,
						10);
		SliderAndSpinnerComboPanel prepCapcitySlider = 
				new SliderAndSpinnerComboPanel(
						PREP_CAPACITY_SLIDER_COMBO,
						"Prep capcacity per time interval:",
						1,
						100,
						50);
		
		this.waitQueueLabel = new JLabel("Wait Queue Total: ");
		this.orderQueueLabel = new JLabel("Order Queue Total: ");
		
		this.setLayout(new GridLayout(5, 1));
		this.add(timeIntervalSlider);
		this.add(patronEatTimeSlider);
		this.add(prepCapcitySlider);
		this.add(this.waitQueueLabel);
		this.add(this.orderQueueLabel);
		
		timeIntervalSlider.addChangeListener(this);
		patronEatTimeSlider.addChangeListener(this);
		prepCapcitySlider.addChangeListener(this);
		
		SystemInterface systemInterface = SystemInterface.getInstance();
		WaitingQueue customerQueue = systemInterface.getWaitingQueue();
		customerQueue.addObserver(this);
		OrderQueue orders = systemInterface.getOrders();
		orders.addObserver(this);
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		if(e.getSource() instanceof SliderAndSpinnerComboPanel) {
			// The timeIntervalSlider has been changed,
			// update the value in the simulator
			SliderAndSpinnerComboPanel source = 
					(SliderAndSpinnerComboPanel)e.getSource();
			if(source.getPanelName().equals(TIME_INTERVAL_SLIDER_COMBO)) {
				simulator.getContext().setTimeIntervals(source.getValue());
			}
			else if(source.getPanelName().equals(PATRON_EAT_TIME_SLIDER_COMBO)) {
				simulator.getContext().setPatronEatTime(source.getValue());
			}
			else if(source.getPanelName().equals(PREP_CAPACITY_SLIDER_COMBO)) {
				simulator.getContext().setPrepCapacity(source.getValue());
			}
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		SystemInterface systemInterface = SystemInterface.getInstance();
		
		if (o == systemInterface.getWaitingQueue()) {
			this.waitQueueLabel.setText("Wait Queue Total: " + systemInterface.getWaitingQueue().size());
		}
		else if(o == systemInterface.getOrders()) {
			this.orderQueueLabel.setText("Order Queue Total: " + systemInterface.getOrders().size());
		}
		
	}
}
